-
Notifications
You must be signed in to change notification settings - Fork 818
Fix fetching old access_token from refresh_token #810
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix fetching old access_token from refresh_token #810
Conversation
Pull Request Test Coverage Report for Build 1331
💛 - Coveralls |
Pull Request Test Coverage Report for Build 1322
💛 - Coveralls |
b0ce48f to
a37d77d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@scaredcat Please create a new PR with a CHANGELOG entry documenting there's a bug fix. I think that qualifies as a user-relevant change. Thanks!
|
Issue
When I scale my back-end to have multiple django instances running to help with growing server demand I sometime receive the following stacktrace error:
This is due to multiple refresh_token requests being sent from the same client to
/api/oauth2/token/where the requests are handled in parallel by the back-end.oauthlibtries to validate the refresh tokenhttps://github.com/oauthlib/oauthlib/blob/b71636e85f845b79b5a56de6480fcba9d1415720/oauthlib/oauth2/rfc6749/grant_types/refresh_token.py#L58
which then calls the
validate_refresh_tokenindjago-oauth-toolkithttps://github.com/oauthlib/oauthlib/blob/b71636e85f845b79b5a56de6480fcba9d1415720/oauthlib/oauth2/rfc6749/grant_types/refresh_token.py#L115-L116
The
refresh_tokenis read from the database and attached to therequestobjecthttps://github.com/jazzband/django-oauth-toolkit/blob/eb381c30affa60a0465a8a2f2c5ca0890ece5362/oauth2_provider/oauth2_validators.py#L637-L642
It then calls
get_original_scopeshttps://github.com/oauthlib/oauthlib/blob/b71636e85f845b79b5a56de6480fcba9d1415720/oauthlib/oauth2/rfc6749/grant_types/refresh_token.py#L122-L123
which in
django-oauth-toolkitreads theaccess_tokenfrom therefresh_tokenthis requires a db lookuphttps://github.com/jazzband/django-oauth-toolkit/blob/eb381c30affa60a0465a8a2f2c5ca0890ece5362/oauth2_provider/oauth2_validators.py#L624
later
oauthlibsaves the tokenhttps://github.com/oauthlib/oauthlib/blob/b71636e85f845b79b5a56de6480fcba9d1415720/oauthlib/oauth2/rfc6749/grant_types/refresh_token.py#L70
which eventually calls
save_bearer_tokenhttps://github.com/oauthlib/oauthlib/blob/b71636e85f845b79b5a56de6480fcba9d1415720/oauthlib/oauth2/rfc6749/request_validator.py#L315
and then
revoke()therefresh_tokenhttps://github.com/jazzband/django-oauth-toolkit/blob/eb381c30affa60a0465a8a2f2c5ca0890ece5362/oauth2_provider/oauth2_validators.py#L532
which in tern deletes the access token.
If you have two servers you can have
Server 1: (1) -> (2) -> (3) -> (4)
Server 2: (1) -> (2) ---------------> (3) -> (4)
Notice server 2 only gets to check the
refresh_tokenafter server 1 has already revoked (deleted) theaccess_tokenthat is attached to therefresh_tokencausing the error on server 2 (stack-trace) above.Description of the Change
Ensure that a database lookup is not required to get the
access_tokenfrom therefresh_tokenin case another parallel refresh request has already removed thataccess_tokenfrom the database